package net.shopxx.boot;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import net.shopxx.security.AuthorizingRealm;

@Configuration
public class ShiroConfig {
    
    @Autowired
    private net.shopxx.security.LogoutFilter logoutFilter;
    
    @Bean
    public ShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setUnauthorizedUrl("/common/error/unauthorized");
        
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
        
        filterChainDefinitionMap.put("/member/register","anon");
        filterChainDefinitionMap.put("/member/register/**","anon");
        filterChainDefinitionMap.put("/member/login","memberAuthc");
        filterChainDefinitionMap.put("/member/logout","logout");

        filterChainDefinitionMap.put("/order/**","memberAuthc,perms[member]");

        filterChainDefinitionMap.put("/consultation/add/*","memberAuthc,perms[member]");
        filterChainDefinitionMap.put("/consultation/save","memberAuthc,perms[member]");

        filterChainDefinitionMap.put("/review/add/*","memberAuthc,perms[member]");
        filterChainDefinitionMap.put("/review/save","memberAuthc,perms[member]");

        filterChainDefinitionMap.put("/member/**","memberAuthc,perms[member]");

        filterChainDefinitionMap.put("/admin","anon");
        filterChainDefinitionMap.put("/admin/","anon");
        filterChainDefinitionMap.put("/admin/login","adminAuthc");
        filterChainDefinitionMap.put("/admin/logout","logout");

        filterChainDefinitionMap.put("/admin/product/**","adminAuthc,perms[admin:product]");
        filterChainDefinitionMap.put("/admin/stock/**","adminAuthc,perms[admin:stock]");
        filterChainDefinitionMap.put("/admin/product_category/**","adminAuthc,perms[admin:productCategory]");
        filterChainDefinitionMap.put("/admin/product_tag/**","adminAuthc,perms[admin:productTag]");
        filterChainDefinitionMap.put("/admin/parameter/**","adminAuthc,perms[admin:parameter]");
        filterChainDefinitionMap.put("/admin/attribute/**","adminAuthc,perms[admin:attribute]");
        filterChainDefinitionMap.put("/admin/specification/**","adminAuthc,perms[admin:specification]");
        filterChainDefinitionMap.put("/admin/brand/**","adminAuthc,perms[admin:brand]");
        filterChainDefinitionMap.put("/admin/product_notify/**","adminAuthc,perms[admin:productNotify]");

        filterChainDefinitionMap.put("/admin/order/**","adminAuthc,perms[admin:order]");
        filterChainDefinitionMap.put("/admin/print/**","adminAuthc,perms[admin:print]");
        filterChainDefinitionMap.put("/admin/order_payment/**","adminAuthc,perms[admin:orderPayment]");
        filterChainDefinitionMap.put("/admin/order_refunds/**","adminAuthc,perms[admin:orderRefunds]");
        filterChainDefinitionMap.put("/admin/order_shipping/**","adminAuthc,perms[admin:orderShipping]");
        filterChainDefinitionMap.put("/admin/order_returns/**","adminAuthc,perms[admin:orderReturns]");
        filterChainDefinitionMap.put("/admin/delivery_center/**","adminAuthc,perms[admin:deliveryCenter]");
        filterChainDefinitionMap.put("/admin/delivery_template/**","adminAuthc,perms[admin:deliveryTemplate]");

        filterChainDefinitionMap.put("/admin/member/**","adminAuthc,perms[admin:member]");
        filterChainDefinitionMap.put("/admin/member_rank/**","adminAuthc,perms[admin:memberRank]");
        filterChainDefinitionMap.put("/admin/member_attribute/**","adminAuthc,perms[admin:memberAttribute]");
        filterChainDefinitionMap.put("/admin/point/**","adminAuthc,perms[admin:point]");
        filterChainDefinitionMap.put("/admin/deposit/**","adminAuthc,perms[admin:deposit]");
        filterChainDefinitionMap.put("/admin/review/**","adminAuthc,perms[admin:review]");
        filterChainDefinitionMap.put("/admin/consultation/**","adminAuthc,perms[admin:consultation]");
        filterChainDefinitionMap.put("/admin/message_config/**","adminAuthc,perms[admin:messageConfig]");


        filterChainDefinitionMap.put("/admin/navigation/**","adminAuthc,perms[admin:navigation]");
        filterChainDefinitionMap.put("/admin/article/**","adminAuthc,perms[admin:article]");
        filterChainDefinitionMap.put("/admin/article_category/**","adminAuthc,perms[admin:articleCategory]");
        filterChainDefinitionMap.put("/admin/article_tag/**","adminAuthc,perms[admin:articleTag]");
        filterChainDefinitionMap.put("/admin/friend_link/**","adminAuthc,perms[admin:friendLink]");
        filterChainDefinitionMap.put("/admin/ad_position/**","adminAuthc,perms[admin:adPosition]");
        filterChainDefinitionMap.put("/admin/ad/**","adminAuthc,perms[admin:ad]");
        filterChainDefinitionMap.put("/admin/template/**","adminAuthc,perms[admin:template]");
        filterChainDefinitionMap.put("/admin/cache/**","adminAuthc,perms[admin:cache]");

        filterChainDefinitionMap.put("/admin/promotion/**","adminAuthc,perms[admin:promotion]");
        filterChainDefinitionMap.put("/admin/coupon/**","adminAuthc,perms[admin:coupon]");
        filterChainDefinitionMap.put("/admin/seo/**","adminAuthc,perms[admin:seo]");

        filterChainDefinitionMap.put("/admin/setting/**","adminAuthc,perms[admin:setting]");
        filterChainDefinitionMap.put("/admin/area/**","adminAuthc,perms[admin:area]");
        filterChainDefinitionMap.put("/admin/payment_method/**","adminAuthc,perms[admin:paymentMethod]");
        filterChainDefinitionMap.put("/admin/shipping_method/**","adminAuthc,perms[admin:shippingMethod]");
        filterChainDefinitionMap.put("/admin/freight_config/**","adminAuthc,perms[admin:freightConfig]");
        filterChainDefinitionMap.put("/admin/delivery_corp/**","adminAuthc,perms[admin:deliveryCorp]");
        filterChainDefinitionMap.put("/admin/payment_plugin/**","adminAuthc,perms[admin:paymentPlugin]");
        filterChainDefinitionMap.put("/admin/storage_plugin/**","adminAuthc,perms[admin:storagePlugin]");
        filterChainDefinitionMap.put("/admin/login_plugin/**","adminAuthc,perms[admin:loginPlugin]");
        filterChainDefinitionMap.put("/admin/admin/**","adminAuthc,perms[admin:admin]");
        filterChainDefinitionMap.put("/admin/role/**","adminAuthc,perms[admin:role]");
        filterChainDefinitionMap.put("/admin/message/**","adminAuthc,perms[admin:message]");
        filterChainDefinitionMap.put("/admin/audit_log/**","adminAuthc,perms[admin:auditLog]");
        
        filterChainDefinitionMap.put("/admin/**","adminAuthc");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        
        Map<String,Filter> filters = new LinkedHashMap<>();
        net.shopxx.security.AuthenticationFilter memberAuthenticationFilter = memberAuthenticationFilter();
        memberAuthenticationFilter.setUserClass(net.shopxx.entity.Member.class);
        memberAuthenticationFilter.setLoginUrl("/member/login");
        memberAuthenticationFilter.setSuccessUrl("/");
        filters.put("memberAuthc", memberAuthenticationFilter);
        
        net.shopxx.security.AuthenticationFilter adminAuthenticationFilter = adminAuthenticationFilter();
        adminAuthenticationFilter.setUserClass(net.shopxx.entity.Admin.class);
        adminAuthenticationFilter.setLoginUrl("/admin/login");
        adminAuthenticationFilter.setSuccessUrl("/admin/index");
        filters.put("adminAuthc", adminAuthenticationFilter);
        
        filters.put("logout", logoutFilter);
        
        shiroFilterFactoryBean.setFilters(filters);
        return shiroFilterFactoryBean;
    }
    
    @Bean
    public net.shopxx.security.AuthenticationFilter memberAuthenticationFilter(){
        return new net.shopxx.security.AuthenticationFilter();
    }
    @Bean
    public net.shopxx.security.AuthenticationFilter adminAuthenticationFilter(){
        return new net.shopxx.security.AuthenticationFilter();
    }
    
    
    @Bean
    public org.apache.shiro.mgt.SecurityManager securityManager(EhCacheManager shiroCacheManager){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(authorizingRealm());
        defaultWebSecurityManager.setCacheManager(shiroCacheManager);
        return defaultWebSecurityManager;
    }
    
    @Bean
    public AuthorizingRealm authorizingRealm(){
        AuthorizingRealm authorizingRealm = new AuthorizingRealm();
        authorizingRealm.setAuthorizationCacheName("authorization");
        return authorizingRealm;
    }
    
    @Bean
    public EhCacheManager shiroCacheManager(@Autowired EhCacheManagerFactoryBean ehCacheManagerFactoryBean){
        EhCacheManager shiroEhCacheManager = new EhCacheManager();
        shiroEhCacheManager.setCacheManager(ehCacheManagerFactoryBean.getObject());
        return shiroEhCacheManager;
    }
    
    @Bean
    public MethodInvokingFactoryBean methodInvokingFactoryBean(org.apache.shiro.mgt.SecurityManager securityManager){
        MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
        methodInvokingFactoryBean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
        methodInvokingFactoryBean.setArguments(new Object[]{securityManager});
        return methodInvokingFactoryBean;
    }
    

}
